package com.ai.bitcoin.helper;

import com.ai.bitcoin.jpa.entity.BccNews;
import com.ai.bitcoin.jpa.service.BccNewsService;
import com.ai.bitcoin.jpa.service.CoinPriceEstimateService;
import com.ai.bitcoin.redis.service.BccRedisService;
import com.ai.bitcoin.util.JacksonUtils;
import com.ai.bitcoin.utils.MathUtil;
import com.ai.bitcoin.vo.*;
import com.alibaba.fastjson.JSONArray;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import net.sf.json.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 生成Html报告接口帮助类
 * Created by gulj on 2018/6/11.
 */
@Component
@Slf4j
public class HtmlReportParseHelper {


    @Autowired
    private CoinPriceEstimateService coinPriceEstimateService;

    @Autowired
    private BccRedisService bccRedisService;

    @Autowired
    private BccNewsService bccNewsService;


    /**
     * 解析雷达图
     *
     * @param rank
     * @return
     */
    public static List<HtmlReportCoinRadarMapVO> parseRadarMap(JSONObject rank) {

        // 综合  相对于昨日指数,变化幅度为
        HtmlReportCoinRadarMapVO complexVO = new HtmlReportCoinRadarMapVO();
        complexVO.setName("综合");
        complexVO.setScore(MathUtil.round(Double.valueOf(rank.optString("valueScore")), 2));
        complexVO.setScoreYesterDay(MathUtil.round(Double.valueOf(rank.optString("valueScoreYesterday")), 2));
        complexVO.setScoreChange(MathUtil.round(Double.valueOf(rank.optString("valueScoreChange")), 2));

        // 排名  今日排名,相对于昨日排名, 变化幅度为
        HtmlReportCoinRadarMapVO rankVO = new HtmlReportCoinRadarMapVO();
        rankVO.setName("今日排名");
        rankVO.setScore(rank.optString("rankValueToday"));
        rankVO.setScoreYesterDay(rank.optString("rankValueYesterday"));
        rankVO.setScoreChange(rank.optString("valueUp"));


        // 击败率 击败率,相对于昨日击败率,变化幅度为
        HtmlReportCoinRadarMapVO defeatFailVO = new HtmlReportCoinRadarMapVO();
        defeatFailVO.setScore(rank.optString("valueScoreDefeat"));
        defeatFailVO.setScoreYesterDay(MathUtil.round(Double.valueOf(rank.optString("valueScoreDefeatYesterday")), 2));
        defeatFailVO.setScoreChange(MathUtil.round(Double.valueOf(rank.optString("valueScoreDefeatChange")), 2));


        // 六大指数

        // 1.供给指数
        HtmlReportCoinRadarMapVO supplyIndex = new HtmlReportCoinRadarMapVO();
        supplyIndex.setName("供给系数");
        supplyIndex.setScore(MathUtil.round(Double.valueOf(rank.optString("supplyScore")), 2));
        supplyIndex.setScoreYesterDay(MathUtil.round(Double.valueOf((rank.optString("supplyScoreYesterday") == null || StringUtils.isBlank(rank.optString("supplyScoreYesterday"))) ? "0" : rank.optString("supplyScoreYesterday")), 2));
        supplyIndex.setScoreChange(MathUtil.round(Double.valueOf((rank.optString("supplyScoreChange") == null || StringUtils.isBlank(rank.optString("supplyScoreYesterday"))) ? "0" : rank.optString("supplyScoreChange")), 2));

        // 2.安全指数
        HtmlReportCoinRadarMapVO safeIndex = new HtmlReportCoinRadarMapVO();
        safeIndex.setName("安全指数");
        safeIndex.setScore(MathUtil.round(Double.valueOf(rank.optString("safeScore")), 2));
        safeIndex.setScoreYesterDay(MathUtil.round(Double.valueOf((rank.optString("safeScoreYesterday") == null || StringUtils.isBlank(rank.optString("supplyScoreYesterday"))) ? "0" : rank.optString("safeScoreYesterday")), 2));
        safeIndex.setScoreChange(MathUtil.round(Double.valueOf((rank.optString("safeScoreChange") == null || StringUtils.isBlank(rank.optString("supplyScoreYesterday"))) ? "0" : rank.optString("safeScoreChange")), 2));


        // 3.货币属性
        HtmlReportCoinRadarMapVO innerIndex = new HtmlReportCoinRadarMapVO();
        innerIndex.setName("货币属性");
        innerIndex.setScore(MathUtil.round(Double.valueOf(rank.optString("innerScore")), 2));
        innerIndex.setScoreYesterDay(MathUtil.round(Double.valueOf((rank.optString("innerScoreYesterday") == null || StringUtils.isBlank(rank.optString("supplyScoreYesterday"))) ? "0" : rank.optString("innerScoreYesterday")), 2));
        innerIndex.setScoreChange(MathUtil.round(Double.valueOf((rank.optString("innerScoreChange") == null || StringUtils.isBlank(rank.optString("supplyScoreYesterday"))) ? "0" : rank.optString("innerScoreChange")), 2));


        // 4.需求指数
        HtmlReportCoinRadarMapVO needIndex = new HtmlReportCoinRadarMapVO();
        needIndex.setName("需求指数");
        needIndex.setScore(MathUtil.round(Double.valueOf(rank.optString("needScore")), 2));
        needIndex.setScoreYesterDay(MathUtil.round(Double.valueOf((rank.optString("needScoreYesterday") == null || StringUtils.isBlank(rank.optString("supplyScoreYesterday"))) ? "0" : rank.optString("needScoreYesterday")), 2));
        needIndex.setScoreChange(MathUtil.round(Double.valueOf((rank.optString("needScoreChange") == null || StringUtils.isBlank(rank.optString("supplyScoreYesterday"))) ? "0" : rank.optString("needScoreChange")), 2));


        // 5.情绪指数
        HtmlReportCoinRadarMapVO moodIndex = new HtmlReportCoinRadarMapVO();
        moodIndex.setName("情绪指数");
        moodIndex.setScore(MathUtil.round(Double.valueOf(rank.optString("moodScore")), 2));
        moodIndex.setScoreYesterDay(MathUtil.round(Double.valueOf((rank.optString("moodScoreYesterday") == null || StringUtils.isBlank(rank.optString("supplyScoreYesterday"))) ? "0" : rank.optString("moodScoreYesterday")), 2));
        moodIndex.setScoreChange(MathUtil.round(Double.valueOf((rank.optString("moodScoreChange") == null || StringUtils.isBlank(rank.optString("supplyScoreYesterday"))) ? "0" : rank.optString("moodScoreChange")), 2));


        // 6.未来指数
        HtmlReportCoinRadarMapVO futureIndex = new HtmlReportCoinRadarMapVO();
        futureIndex.setName("未来指数");
        futureIndex.setScore(MathUtil.round(Double.valueOf(rank.optString("futureScore")), 2));
        futureIndex.setScoreYesterDay(MathUtil.round(Double.valueOf((rank.optString("futureScoreYesterday") == null || StringUtils.isBlank(rank.optString("supplyScoreYesterday"))) ? "0" : rank.optString("futureScoreYesterday")), 2));
        futureIndex.setScoreChange(MathUtil.round(Double.valueOf((rank.optString("futureScoreChange") == null || StringUtils.isBlank(rank.optString("supplyScoreYesterday"))) ? "0" : rank.optString("futureScoreChange")), 2));


        return Lists.newArrayList(complexVO, rankVO, defeatFailVO, supplyIndex, safeIndex, innerIndex, needIndex, moodIndex, futureIndex);

    }


    /**
     * 解析舆情数据
     *
     * @param digestNews
     * @return
     */
    public static List<HtmlReportCoinYuQingVO> parseYuQing(List<Map<String, Object>> digestNews) {
        if (digestNews == null || digestNews.size() == 0) {
            return null;
        }
        List<HtmlReportCoinYuQingVO> yuQingVOList = new ArrayList<>();
        for (Map<String, Object> digestNew : digestNews) {
            HtmlReportCoinYuQingVO yuQingVO = new HtmlReportCoinYuQingVO();
            yuQingVO.setNewsImg(digestNew.get("thumbnail"));
            yuQingVO.setNewsTitle(digestNew.get("title"));
            yuQingVO.setNewsHref(digestNew.get("newsUrl"));
            yuQingVO.setNewsContent(digestNew.get("description"));
            yuQingVO.setPessiNum(digestNew.get("bearCount"));
            yuQingVO.setOptiNum(digestNew.get("bullCount"));

            yuQingVOList.add(yuQingVO);
        }
        return yuQingVOList;
    }


    /**
     * 折线图
     *
     * @return
     */
    public List<HtmlReportLineChartVO> parseLineChart(String bccId) {
        String result = coinPriceEstimateService.queryCoinTrend(bccId);
        if (StringUtils.isEmpty(result)) {
            return null;
        }
        return JSONArray.parseArray(result, HtmlReportLineChartVO.class);
    }

    /**
     * 今日推荐
     *
     * @return
     */
    public List<HtmlReportCoinTodayRecommendVO> parseTodayRecommend(String date) {
        String todayRecommend = coinPriceEstimateService.findTodayRecommend(date);
        JSONArray objects = com.alibaba.fastjson.JSONObject.parseArray(todayRecommend);

        if (objects == null || objects.size() < 1) {
            return null;
        }

        List<HtmlReportCoinTodayRecommendVO> todayRecommendVOList = new ArrayList<>();
        for (int i = 0; i < objects.size(); i++) {
            JSONArray result = objects.getJSONArray(i);
            if (result != null && result.size() > 0) {
                HtmlReportCoinTodayRecommendVO vo = new HtmlReportCoinTodayRecommendVO();
                vo.setNameCn(result.get(0));
                vo.setNameEn(result.get(1));
                vo.setUpRate(result.get(2));
                vo.setBccId(result.get(3));
                todayRecommendVOList.add(vo);
            }
        }
        return todayRecommendVOList;
    }


    /**
     * 解析报告基础信息
     *
     * @param jsonObject
     * @return
     */
    public static HtmlReportCoinBasicInfoVO parseBasicInfo(JSONObject jsonObject) {
        HtmlReportCoinBasicInfoVO basicInfoVO = new HtmlReportCoinBasicInfoVO();
        JSONObject basicRealInfo = jsonObject.getJSONObject("basicRealInfo");
        if (basicRealInfo != null && basicRealInfo.keySet().size() > 0) {
            // 当前代币
            basicInfoVO.setAvailableSupply(basicRealInfo.get("availableSupply"));
            // 总发行代币
            basicInfoVO.setTotalSupply(basicRealInfo.get("totalSupply"));
            // 上线时间
            basicInfoVO.setOnlineTime(basicRealInfo.get("onlineTime"));
            // 发行代币单位
            basicInfoVO.setSymbol(basicRealInfo.get("symbol"));
            // logo
            basicInfoVO.setLogoUrl(basicRealInfo.get("logoUrl"));
            // 中文名
            basicInfoVO.setNameCn(basicRealInfo.get("nameCn"));
            // 英文名
            basicInfoVO.setNameEn(basicRealInfo.get("nameEn"));
            // 24小时成交量
            basicInfoVO.setVolume24h(basicRealInfo.get("volume24h"));
        }
        try {
            net.sf.json.JSONArray h24PriceArr = jsonObject.getJSONArray("h24Price");
            if (h24PriceArr != null && h24PriceArr.size() > 0) {
                JSONObject h24PriceJSONObject = h24PriceArr.getJSONObject(0);
                basicInfoVO.setChange1d(h24PriceJSONObject.get("change1d"));
                basicInfoVO.setChange1h(h24PriceJSONObject.get("change1h"));
                basicInfoVO.setChange7d(h24PriceJSONObject.get("change7d"));
                basicInfoVO.setMarketCap(h24PriceJSONObject.get("marketCap"));
                basicInfoVO.setPriceCny(h24PriceJSONObject.get("priceCny"));
                basicInfoVO.setPriceUsd(h24PriceJSONObject.get("priceUsd"));

            }
        } catch (Exception e) {
            log.warn(e.getMessage());
        }

        return basicInfoVO;
    }


    /**
     * 每日数据
     *
     * @return
     */
    public static HtmlReportCoinDailyInfoVO parseDailyInfo(JSONObject jsonObject) {
        JSONObject basicInfo = jsonObject.optJSONObject("basicInfo");
        String nameEn = basicInfo.optString("nameEn");
        String nameCn = basicInfo.optString("nameCn");

        HtmlReportCoinDailyInfoVO htmlReportCoinDailyInfoVO = new HtmlReportCoinDailyInfoVO(nameEn, nameCn);


        htmlReportCoinDailyInfoVO.setCreateReportTime(new SimpleDateFormat("yyyy-MM-dd").format(new Date()));
        return htmlReportCoinDailyInfoVO;
    }


    /**
     * 处理非订阅数据
     */
    public static class Subscription {

        /**
         * 订阅所有数据
         *
         * @return
         */
        public static HtmlReportGenerateVO allReport(JSONObject jsonObject, List<HtmlReportLineChartVO> lineChartVOList, List<HtmlReportCoinTodayRecommendVO> todayRecommendVOList, List<BccNews> bccNewsList) {

            HtmlReportGenerateVO reportGenerateVO = new HtmlReportGenerateVO();
            // 舆情
            //reportGenerateVO.setYuQingVOList(parseYuQing(getDigestNews(jsonObject)));
            reportGenerateVO.setBccNewsList(bccNewsList);

            // 雷达图
            JSONObject rank = jsonObject.optJSONObject("rank");
            reportGenerateVO.setRadarMapVOList(parseRadarMap(rank));
            // 折线图
            reportGenerateVO.setLineChartVOList(lineChartVOList);
            // 币的每日信息
            reportGenerateVO.setDailyInfo(parseDailyInfo(jsonObject));
            // 币的基础信息
            reportGenerateVO.setBasicInfo(parseBasicInfo(jsonObject));

            // 币报告的推荐部分数据
            reportGenerateVO.setTodayRecommendVOList(todayRecommendVOList);

            return reportGenerateVO;
        }

        /**
         * 订阅部分数据（非订阅）
         *
         * @return
         */
        public static HtmlReportGenerateVO partReport(HtmlReportGenerateVO reportGenerateVO) {
            // 数据进行非订阅业务处理

            // 舆情 限制2条
            List<BccNews> bccNewsList = reportGenerateVO.getBccNewsList();
            if (null != bccNewsList && bccNewsList.size() > 0) {
                reportGenerateVO.setBccNewsList(reportGenerateVO.getBccNewsList().stream().limit(2).collect(Collectors.toList()));
            }

            // 今日推荐限制三条
            List<HtmlReportCoinTodayRecommendVO> todayRecommendVOList = reportGenerateVO.getTodayRecommendVOList();
            if (null != todayRecommendVOList && todayRecommendVOList.size() > 0) {
                reportGenerateVO.setTodayRecommendVOList(reportGenerateVO.getTodayRecommendVOList().stream().limit(3).collect(Collectors.toList()));
            }

            // 折线图
            List<HtmlReportLineChartVO> lineChartVOList = reportGenerateVO.getLineChartVOList();
            if (lineChartVOList != null && lineChartVOList.size() > 0) {
                for (HtmlReportLineChartVO lineChartVO : lineChartVOList) {
                    lineChartVO.setProb(null);
                    lineChartVO.setLowerBoundMean(null);
                    lineChartVO.setUppderBoundMean(null);
                }
            }
            reportGenerateVO.setLineChartVOList(lineChartVOList);

            //  六大供给指数
            List<HtmlReportCoinRadarMapVO> radarMapVOList = reportGenerateVO.getRadarMapVOList();
            for (int i = 0; i < radarMapVOList.size(); i++) {
                if (i > 2) {
                    radarMapVOList.get(i).setScoreChange(null);
                }
            }
            reportGenerateVO.setRadarMapVOList(radarMapVOList);
            return reportGenerateVO;
        }

    }


    /**
     * 获取元数据
     *
     * @param bccId
     * @return
     */
    public JSONObject getJsonObject(String bccId) {
        return bccRedisService.getReport(bccId);
    }

    private static List<Map<String, Object>> getDigestNews(JSONObject jsonObject) {
        List<Map<String, Object>> digestNews = null;
        if (jsonObject.optString("digestNews") != null) {
            digestNews = JacksonUtils.fromJsonToList(jsonObject.optString("digestNews"), ArrayList.class, HashMap.class);
        }
        return digestNews;
    }

}
